package doc1.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslHandler;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;

public class ClientMain {
    public static void main(String[] args) throws Exception{
        EventLoopGroup group=new NioEventLoopGroup();
        Bootstrap boot=new Bootstrap();
        SSLContext sslContext = createSSLContext("JKS","C://Users//Xiaojiuc//Desktop//6149131_zxfk.ltd_jks//6149131_zxfk.ltd.jks","QUTqiXxt");
        //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信
        SSLEngine engine = sslContext.createSSLEngine();
        engine.setUseClientMode(true);
        boot.option(ChannelOption.SO_KEEPALIVE,true)
                .option(ChannelOption.TCP_NODELAY,true)
                .group(group)
                .handler(new LoggingHandler(LogLevel.INFO))
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ByteBufAllocator alloc = socketChannel.alloc();
                        ChannelPipeline p = socketChannel.pipeline();
                        p.addLast("ssl",new SslHandler(engine));
                        p.addLast(new ChannelHandler[]{new HttpClientCodec(),
                                new HttpObjectAggregator(1024*1024*10)});
                        p.addLast("hookedHandler", new WebSocketClientHandler());
                    }
                });
        URI websocketURI = new URI("wss://wspri.coinall.ltd:8443/ws/v5/public");
//        URI websocketURI = new URI("ws://120.48.18.54:30002/websocket/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ1aWQiOjIsIm9hciI6IkJNSkwiLCJuYmYiOjE2MzkwMzgyMTAsInVubSI6IueuoeeQhuWRmCIsImlzcyI6Inh5LW1peC14aWFveGkiLCJvaWQiOjQxLCJleHAiOjE2MzkxMjQ2MTAsImlhdCI6MTYzOTAzODIxMCwianRpIjoiYTYxNDcwMmNjMzBmNGNmZWFiMDU4MmU4MjYzNzczMWUiLCJ0aWQiOjAsIm9ubSI6IumDqOmXqOe7j-eQhiJ9.ZLBggs2wWdyQ_qPFxpcKz837C2AZ7r3jguq0ONcvtF5aB7oAhfT1hLiTijr7E1QO1wp0hm9_hVTOA5jP04so8A");
        HttpHeaders httpHeaders = new DefaultHttpHeaders();
        //进行握手
        WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(websocketURI, WebSocketVersion.V13, (String)null, true,httpHeaders);
        System.out.println("connect");
        final Channel channel=boot.connect(websocketURI.getHost(),websocketURI.getPort()).sync().channel();
        WebSocketClientHandler handler = (WebSocketClientHandler)channel.pipeline().get("hookedHandler");
        handler.setHandshaker(handshaker);
        handshaker.handshake(channel);
        //阻塞等待是否握手成功
        handler.handshakeFuture().sync();

        String s ="{ \"op\": \"subscribe\", \"args\": [ { \"channel\": \"tickers-3s\", \"instId\": \"ETH-USDT\" } ] }";
        ByteBuf bf= Unpooled.buffer().writeBytes(s.getBytes(StandardCharsets.UTF_8));
        BinaryWebSocketFrame binaryWebSocketFrame=new BinaryWebSocketFrame(bf);
    }



    public static SSLContext createSSLContext(String type , String path , String password) throws Exception {
        KeyStore ks = KeyStore.getInstance(type); /// "JKS"
        InputStream ksInputStream = new FileInputStream(path); /// 证书存放地址
        ks.load(ksInputStream, password.toCharArray());
        //KeyManagerFactory充当基于密钥内容源的密钥管理器的工厂。
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//getDefaultAlgorithm:获取默认的 KeyManagerFactory 算法名称。
        kmf.init(ks, password.toCharArray());
        //SSLContext的实例表示安全套接字协议的实现，它充当用于安全套接字工厂或 SSLEngine 的工厂。
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), null, null);
        return sslContext;
    }
}
